home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 11 Learning / 04 Mommersteeg / Tennis / tennis.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-09-30  |  9.7 KB  |  341 lines

  1. //----------------------------------------------------------------------------------------------
  2. // Sequential Prediction Demo: The positioning pattern
  3. // 
  4. // Author:  Fri Mommersteeg
  5. // Date:    10-09-2001
  6. // File:    Tennis.cpp
  7. //----------------------------------------------------------------------------------------------
  8.  
  9. //----------------------------------------------------------------------------------------------
  10. // Include files
  11. //----------------------------------------------------------------------------------------------
  12.  
  13. #include "stdafx.h"
  14. #include "ball.h"
  15. #include "gamer.h"
  16. #include "aibot.h"
  17. #include "patternbot.h"
  18. #include "soundbuffer.h"
  19. #include "tennisfield.h"
  20.  
  21. //----------------------------------------------------------------------------------------------
  22. // Global variables
  23. //----------------------------------------------------------------------------------------------
  24.  
  25. HWND            g_hWnd;
  26. BOOL            g_bActive;
  27. BOOL            g_Freeze;
  28. BOOL            g_Intro;
  29. DWORD            g_FrameRate;
  30. DWORD            g_TargetSpeed;
  31. BOOL            g_bBotTargeting;
  32. LPDDS            imgField;
  33. LPDDS            imgRedCross;
  34. LPDDS            imgIntro;
  35. CTennisBall        ball;
  36. CAiBot            bot;
  37. CTennisField    TennisField;
  38. CSoundBuffer    sndHitBall;
  39. CSoundBuffer    sndBounce;
  40.  
  41. //----------------------------------------------------------------------------------------------
  42. // The gamer object can be replaced by a pattern bot, which is a bot that can generate
  43. // patterns in its behavior. The pattern bot is excellent for making visible the pattern 
  44. // recognition capabilities of sequential prediction. Just define PATTERNBOT_MOVIE, get some
  45. // popcorn, sit back and relax and watch the show! ;-)
  46. //----------------------------------------------------------------------------------------------
  47.  
  48. //#define PATTERNBOT_MOVIE
  49.  
  50. #ifdef PATTERNBOT_MOVIE
  51.  
  52. CPatternBot        gamer;
  53.  
  54. #else
  55.  
  56. CGamer            gamer;
  57.  
  58. #endif // PATTERNBOT_MOVIE
  59.  
  60. //----------------------------------------------------------------------------------------------
  61. // SetupSurfaces(): Creates the DirectDraw Surfaces
  62. //----------------------------------------------------------------------------------------------
  63.  
  64. void SetupSurfaces() {
  65.     CreateSurface(imgField, FIELD_WIDTH, FIELD_HEIGHT);
  66.     CreateSurface(imgRedCross, CROSS_WIDTH, CROSS_HEIGHT);
  67. }
  68.  
  69. //----------------------------------------------------------------------------------------------
  70. // SetupSurfaces(): Loads bitmaps into the DirectDraw surfaces
  71. //----------------------------------------------------------------------------------------------
  72.  
  73. void LoadSurfaces() {
  74.     LoadSurface("tennisfield.bmp", 0, 0, imgField);
  75.     LoadSurface("cross.bmp", 0, 0, imgRedCross);    
  76. }
  77.  
  78. //----------------------------------------------------------------------------------------------
  79. // RestoreAll(): Callback function for my DirectDraw library; restores lost surfaces
  80. //----------------------------------------------------------------------------------------------
  81.  
  82. BOOL RestoreAll(BOOL reinit) {
  83.     if (reinit) {
  84.         BOOL result;
  85.         ShutdownDD();
  86.         result = InitDD(g_hWnd, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 1);
  87.         SetupSurfaces();
  88.         return result;
  89.     }
  90.     LoadSurfaces();
  91.     return TRUE;
  92. }
  93.  
  94. //----------------------------------------------------------------------------------------------
  95. // LoadSamples(): Loads wave files into DirectSound buffers
  96. //----------------------------------------------------------------------------------------------
  97.  
  98. void LoadSamples() {
  99.     sndHitBall.CreateWave(lpds, "hitball.wav");
  100.     sndBounce.CreateWave(lpds, "bounce.wav");
  101. }
  102.  
  103. //----------------------------------------------------------------------------------------------
  104. // GameInit(): Initializes the game
  105. //----------------------------------------------------------------------------------------------
  106.  
  107. void GameInit(HWND hWnd, HINSTANCE hInstance) {    
  108.  
  109.     // initialize global variables
  110.     g_hWnd = hWnd;
  111.     g_Freeze = FALSE;
  112.     g_Intro = TRUE;
  113.     g_FrameRate = DEFAULT_SPEED;
  114.     g_TargetSpeed = DEFAULT_SPEED;
  115.     g_bBotTargeting = FALSE;
  116.  
  117.     // initialize DirectDraw
  118.     if (!InitDD(hWnd, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, 1)) {
  119.         MessageBox(NULL, "Failed to initialize DirectDraw!","Error", 0);
  120.         return;
  121.     }
  122.  
  123.     // set up DirectDraw surfaces and display the intro screen
  124.     SetupSurfaces();
  125.     LoadSurfaces();
  126.     LoadSurface("intro.bmp", 0, 0, lpddss);    
  127.     Flip();
  128.  
  129.     // initialize DirectSound
  130.     if (!InitDS()) {
  131.         MessageBox(NULL, "Failed to initialize DirectSound!", "Error", 0);
  132.         return;
  133.     }
  134.  
  135.     // set up DirectSound buffers
  136.     LoadSamples();
  137.             
  138.     RECT field;
  139.  
  140.     // set up bot play field
  141.     field.left = (SCREEN_WIDTH-FIELD_WIDTH) / 2 + OUTBOX_WIDTH;
  142.     field.right = SCREEN_WIDTH - (SCREEN_WIDTH-FIELD_WIDTH) / 2 - OUTBOX_WIDTH;
  143.     field.top = (SCREEN_HEIGHT-FIELD_HEIGHT) / 2;
  144.     field.bottom = SCREEN_HEIGHT / 2;
  145.  
  146.     // set up bot settings
  147.     bot.SetPlayField(&field);
  148.     bot.SetColor(RGB(0,0,255));
  149.     bot.SetDirection(PADDLE_DOWN);
  150.     bot.SetupAI(&ball, g_bBotTargeting);
  151.  
  152.     // set up gamer play field
  153.     field.left = (SCREEN_WIDTH-FIELD_WIDTH) / 2 + OUTBOX_WIDTH;
  154.     field.right = SCREEN_WIDTH - (SCREEN_WIDTH-FIELD_WIDTH) / 2 - OUTBOX_WIDTH;
  155.     field.top = SCREEN_HEIGHT / 2; 
  156.     field.bottom = SCREEN_HEIGHT-(SCREEN_HEIGHT-FIELD_HEIGHT) / 2;
  157.  
  158.     // set up gamer settings
  159.     gamer.SetPlayField(&field);
  160.     gamer.SetColor(RGB(255,0,0));    
  161.     gamer.SetDirection(PADDLE_UP);    
  162.  
  163. #ifdef PATTERNBOT_MOVIE
  164.  
  165.     gamer.SetupAI(&ball, TRUE);
  166.     gamer.SetPatternSize(3);
  167.  
  168. #endif
  169.  
  170.     // set up entire tennis field
  171.     field.left = (SCREEN_WIDTH-FIELD_WIDTH) / 2;
  172.     field.right = SCREEN_WIDTH - (SCREEN_WIDTH-FIELD_WIDTH) / 2;
  173.     field.top = (SCREEN_HEIGHT-FIELD_HEIGHT) / 2;
  174.     field.bottom = SCREEN_HEIGHT-(SCREEN_HEIGHT-FIELD_HEIGHT) / 2;
  175.  
  176.     // plug objects into "manager" object
  177.     TennisField.SetupField(&field, &gamer, &bot, &ball);    
  178. }
  179.  
  180. //----------------------------------------------------------------------------------------------
  181. // GameMain(): Main game loop (called from the message loop)
  182. //----------------------------------------------------------------------------------------------
  183.  
  184. void GameMain() {    
  185.     if (!g_Freeze && !g_Intro) {
  186.         TennisField.Update();
  187.     }
  188. }
  189.  
  190. //----------------------------------------------------------------------------------------------
  191. // GameShutDown(): Destroys the game objects and releases allocated memory
  192. //----------------------------------------------------------------------------------------------
  193.  
  194. void GameShutdown() {
  195.     sndHitBall.Release();
  196.     sndBounce.Release();
  197.     ShutdownDS();
  198.     imgField->Release();
  199.     imgRedCross->Release();
  200.     ShutdownDD();
  201. }
  202.  
  203. //----------------------------------------------------------------------------------------------
  204. // WindowProc(): Window handler 
  205. //----------------------------------------------------------------------------------------------
  206.  
  207. LRESULT CALLBACK WindowProc(HWND hWnd, 
  208.                             UINT Msg, 
  209.                             WPARAM wParam, 
  210.                             LPARAM lParam) 
  211. {
  212.     switch(Msg) {    
  213.  
  214.         case WM_ACTIVATEAPP:
  215.             g_bActive = (wParam == WA_ACTIVE) || (wParam == WA_CLICKACTIVE);
  216.             break;
  217.  
  218.         case WM_SETCURSOR:
  219.             SetCursor(NULL);
  220.             break;
  221.  
  222.         case WM_PAINT:
  223.             break;
  224.  
  225.         case WM_KEYDOWN:
  226.             if (g_Intro) {
  227.                 g_Intro = FALSE;
  228.                 TennisField.Start();
  229.             } else {
  230.                 int nVirtKey = (int)wParam;
  231.                 switch (nVirtKey) {
  232.                 case VK_F1: 
  233.                     g_Freeze = !g_Freeze;
  234.                     if (!g_Freeze) {
  235.                         TennisField.Start(); // restart frame-rate counter
  236.                     }
  237.                     break;
  238.                 case VK_F2:
  239.                     g_bBotTargeting = !g_bBotTargeting;
  240.                     bot.EnableTargeting(g_bBotTargeting);
  241.                     break;
  242.                 case VK_F3:
  243.                     ball.SetVelocity(0,0,0);
  244.                     break;
  245.                 case VK_ESCAPE:
  246.                     PostQuitMessage(0);
  247.                     break;
  248.                 }
  249.             }
  250.             break;
  251.  
  252.         case WM_DESTROY: 
  253.             PostQuitMessage(0);            
  254.             break;
  255.  
  256.         default:
  257.             break;
  258.     }
  259.  
  260.     return DefWindowProc(hWnd, Msg, wParam, lParam);
  261. }
  262.  
  263. //----------------------------------------------------------------------------------------------
  264. // WinMain(): Entry point for the application
  265. //----------------------------------------------------------------------------------------------
  266.  
  267. int APIENTRY WinMain(    HINSTANCE hInstance,
  268.                         HINSTANCE hPrevInstance,
  269.                         LPSTR lpCmdLine,
  270.                         int nCmdShow)
  271. {
  272.  
  273.     WNDCLASS    wc;        
  274.     MSG            msg;
  275.     HWND        hWnd;
  276.  
  277.     // set up the window class
  278.     wc.style = CS_HREDRAW | CS_VREDRAW;
  279.     wc.lpfnWndProc = WindowProc;
  280.     wc.cbClsExtra = 0;
  281.     wc.cbWndExtra = 0;
  282.     wc.hInstance = hInstance;
  283.     wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON));
  284.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  285.     wc.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH);
  286.     wc.lpszMenuName = NAME;
  287.     wc.lpszClassName = NAME;
  288.     RegisterClass(&wc);
  289.  
  290.     // create the window
  291.     hWnd = CreateWindowEx(WS_EX_TOPMOST,
  292.                           NAME,
  293.                           TITLE,
  294.                           WS_POPUP,
  295.                           0,
  296.                           0,
  297.                           SCREEN_WIDTH,
  298.                           SCREEN_HEIGHT,
  299.                           NULL,
  300.                           NULL,
  301.                           hInstance,
  302.                           NULL);
  303.     if (!hWnd)
  304.         return FALSE;
  305.  
  306.     // do some other window stuff
  307.     ShowWindow(hWnd, nCmdShow);
  308.     UpdateWindow(hWnd);
  309.     SetFocus(hWnd);
  310.     ShowCursor(FALSE);
  311.  
  312.     // initialize the game
  313.     GameInit(hWnd, hInstance);
  314.     
  315.     // run the message loop
  316.     while (TRUE) {
  317.         if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { 
  318.             if (msg.message == WM_QUIT)
  319.                 break;
  320.     
  321.             TranslateMessage(&msg);
  322.             DispatchMessage(&msg);
  323.         }
  324.     
  325.         if (g_bActive) {
  326.             GameMain();
  327.         } else {
  328.             WaitMessage();
  329.         }
  330.     }
  331.  
  332.  
  333.     // shut down the game
  334.     GameShutdown();
  335.  
  336.     // release the window
  337.     DestroyWindow(hWnd);
  338.  
  339.     return (msg.wParam);
  340. }
  341.